// Polyfills for undici compatibility - MUST be loaded before any imports

// ReadableStream polyfill
if (typeof global.ReadableStream === 'undefined') {
  // @ts-ignore
  global.ReadableStream = require('stream').Readable;
}

// DOMException polyfill
if (typeof global.DOMException === 'undefined') {
  // @ts-ignore
  global.DOMException = class DOMException extends Error {
    constructor(message: string, name: string = 'Error') {
      super(message);
      this.name = name;
    }
  };
}

// File API polyfill
if (typeof global.File === 'undefined') {
  // @ts-ignore
  global.File = class File {
    private _chunks: Buffer[];
    public name: string;
    public size: number;
    public type: string;
    public lastModified: number;

    constructor(chunks: any, filename: string, options: { type?: string; lastModified?: number } = {}) {
      this.name = filename;
      this.size = chunks.reduce((acc: number, chunk: Buffer) => acc + chunk.length, 0);
      this.type = options.type || '';
      this.lastModified = options.lastModified || Date.now();
      this._chunks = chunks;
    }

    arrayBuffer(): Promise<ArrayBuffer> {
      const buffer = Buffer.concat(this._chunks);
      return Promise.resolve(buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength));
    }

    slice(start?: number, end?: number): File {
      const buffer = Buffer.concat(this._chunks);
      const sliced = buffer.slice(start, end);
      return new File([sliced], this.name, { type: this.type });
    }

    stream(): ReadableStream {
      return new ReadableStream({
        start(controller) {
          controller.enqueue(Buffer.concat(this._chunks));
          controller.close();
        }
      });
    }

    text(): Promise<string> {
      return Promise.resolve(Buffer.concat(this._chunks).toString());
    }
  };
}

if (typeof global.Blob === 'undefined') {
  // @ts-ignore
  global.Blob = class Blob {
    private _chunks: Buffer[];
    public size: number;
    public type: string;

    constructor(chunks: Buffer[] = [], options: { type?: string } = {}) {
      this._chunks = chunks;
      this.size = chunks.reduce((acc, chunk) => acc + chunk.length, 0);
      this.type = options.type || '';
    }

    arrayBuffer(): Promise<ArrayBuffer> {
      const buffer = Buffer.concat(this._chunks);
      return Promise.resolve(buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength));
    }

    slice(start?: number, end?: number): Blob {
      const buffer = Buffer.concat(this._chunks);
      const sliced = buffer.slice(start, end);
      return new Blob([sliced], { type: this.type });
    }

    stream(): ReadableStream {
      return new ReadableStream({
        start(controller) {
          controller.enqueue(Buffer.concat(this._chunks));
          controller.close();
        }
      });
    }

    text(): Promise<string> {
      return Promise.resolve(Buffer.concat(this._chunks).toString());
    }
  };
}

export {};